//
// Created by zerax on 2020/10/24.
//

#include "shader_manager.hh"
#include "file_io.hh"

using namespace std;

static shared_ptr<ShaderManager> instance;

shared_ptr<ShaderManager> ShaderManager::getInstance() {
    if (instance == nullptr) {
        instance = shared_ptr<ShaderManager>(new ShaderManager());
    }
    return instance;
}

void ShaderManager::loadShader(const char* name, const char *vert, const char *frag) {
    auto vertShader = glCreateShader(GL_VERTEX_SHADER);
    auto fragShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(vertShader, 1, &vert, nullptr);
    glShaderSource(fragShader, 1, &frag, nullptr);

    glCompileShader(vertShader);
    glCompileShader(fragShader);

    auto program = glCreateProgram();

    glAttachShader(program, vertShader);
    glAttachShader(program, fragShader);
    glLinkProgram(program);

    glDeleteShader(vertShader);
    glDeleteShader(fragShader);

    shaders[name] = shared_ptr<Shader>(new Shader(program));
}


void ShaderManager::loadShaderFromFile(const char *name, const char *vertPath, const char *fragPath) {
    loadShader(name, FileIO::readText(vertPath).c_str(), FileIO::readText(fragPath).c_str());
}

std::shared_ptr<Shader> ShaderManager::getShader(const char *name) {
    return shaders[name];
}


ShaderManager::ShaderManager() = default;
